package com.sample.springbatch.scheduler;

import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zwg
 * @date 2019-05-06 16:59
 **/
@Component
public class SchedulerFactoryService {
    @Autowired
    //@Qualifier("mySchedulerFactoryBean")
    SchedulerFactoryBean schedulerFactoryBean;

    Logger logger = LoggerFactory.getLogger(SchedulerFactoryService.class);




    @PostConstruct
    public void init () throws SchedulerException{
        List<SchedulerInfo> jobList = new ArrayList<>();
        jobList.add(new SchedulerInfo("demoTask_demo","*/10 * * * * ?","com.sample.springbatch.scheduler.DemoTask","demo",""));
        jobList.add(new SchedulerInfo("demoTask_demo1","*/10 * * * * ?","","demo1","demoTask"));


        StringBuilder logBuilder = new StringBuilder("load quartz jobs"+jobList.size()+"个：");
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        for (SchedulerInfo job : jobList) {
            try{
                TriggerKey triggerKey = TriggerKey.triggerKey(job.getName());

                //获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
                CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

                //不存在，创建一个
                if (null == trigger) {
                    JobDetail jobDetail = JobBuilder.newJob(DemoTaskJob.class)
                            .withIdentity(job.getName()).build();
                    jobDetail.getJobDataMap().put("jobInfo", job);
                    //表达式调度构建器  withMisfireHandlingInstructionDoNothing 忽略错误的触发，执行下一个周期
                    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job
                            .getCron()).withMisfireHandlingInstructionDoNothing();

                    //按新的cronExpression表达式构建一个新的trigger
                    trigger = TriggerBuilder.newTrigger().withIdentity(job.getName()).withSchedule(scheduleBuilder).build();

                    scheduler.scheduleJob(jobDetail, trigger);

                    logBuilder.append("add[").append(job.getName()).append("|").append(job.getCron()).append("],");
                } else {
                    // Trigger已存在，那么更新相应的定时设置
                    //表达式调度构建器 withMisfireHandlingInstructionDoNothing 忽略错误的触发，执行下一个周期
                    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job
                            .getCron()).withMisfireHandlingInstructionDoNothing();

                    //按新的cronExpression表达式重新构建trigger
                    trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                            .withSchedule(scheduleBuilder).build();

                    //按新的trigger重新设置job执行
                    scheduler.rescheduleJob(triggerKey, trigger);
                    logBuilder.append("update[").append(job.getName()).append("|").append(job.getCron()).append("],");
                }
            }catch (Exception e){
                logger.error("load job error:",e);
                logBuilder.append("error[").append(job.getName()).append("|").append(job.getCron()).append("|").append(e.getMessage()).append("],");
            }

        }

        logger.info(logBuilder.toString());
    }


    class SchedulerInfo{
        private String name;
        private String cron;
        /**
         * 要实现 @org.quartz.Job 接口
         */
        private String className;

        private String methodName;

        private String beanName;

        public SchedulerInfo() {
        }

        public SchedulerInfo(String name, String cron, String className, String methodName, String beanName) {
            this.name = name;
            this.cron = cron;
            this.className = className;
            this.beanName = beanName;
            this.methodName = methodName;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getCron() {
            return cron;
        }

        public void setCron(String cron) {
            this.cron = cron;
        }

        public String getClassName() {
            return className;
        }

        public void setClassName(String className) {
            this.className = className;
        }

        public String getMethodName() {
            return methodName;
        }

        public void setMethodName(String methodName) {
            this.methodName = methodName;
        }

        public String getBeanName() {
            return beanName;
        }

        public void setBeanName(String beanName) {
            this.beanName = beanName;
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("SchedulerInfo{");
            sb.append("name='").append(name).append('\'');
            sb.append(", cron='").append(cron).append('\'');
            sb.append(", className='").append(className).append('\'');
            sb.append(", methodName='").append(methodName).append('\'');
            sb.append(", beanName='").append(beanName).append('\'');
            sb.append('}');
            return sb.toString();
        }
    }




}
